/*
 * Galaxium Messenger
 * 
 * Copyright (C) 2005-2007 Philippe Durand <draekz@gmail.com>
 * 
 * License: GNU Lesser General Public License (LGPL)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

using System;
using System.Collections.Generic;

using Galaxium.Core;
using csammisrun.OscarLib;

namespace Galaxium.Protocol.Aim
{
	public static class AimPresence
	{
		private static IPresence _online;
		private static IPresence _offline;
		private static IPresence _away;
		private static IPresence _dnd;
		private static IPresence _na;
		private static IPresence _occupied;
		private static IPresence _freeforchat;
		private static IPresence _invisible;
		
		public static IPresence Online
		{
			get
			{
				if (_online == null)
					_online = new OnlinePresence ();
				return _online;
			}
		}
		
		public static IPresence Offline
		{
			get
			{
				if (_offline == null)
					_offline = new OfflinePresence ();
				return _offline;
			}
		}
		
		public static IPresence Away
		{
			get
			{
				if (_away == null)
					_away = new AwayPresence ();
				return _away;
			}
		}
		
		public static IPresence Dnd
		{
			get
			{
				if (_dnd == null)
					_dnd = new DndPresence ();
				return _dnd;
			}
		}
		
		public static IPresence Na
		{
			get
			{
				if (_na == null)
					_na = new NaPresence ();
				return _na;
			}
		}
		
		public static IPresence Occupied
		{
			get
			{
				if (_occupied == null)
					_occupied = new OccupiedPresence ();
				return _occupied;
			}
		}
		
		public static IPresence FreeForChat
		{
			get
			{
				if (_freeforchat == null)
					_freeforchat = new FreeForChatPresence ();
				return _freeforchat;
			}
		}
		
		public static IPresence Invisible
		{
			get
			{
				if (_invisible == null)
					_invisible = new InvisiblePresence ();
				return _invisible;
			}
		}
		
		public static bool IsValidAimPresence (IPresence presence)
		{
			if (presence == null)
				return false;
			
			return presence.Equals (_online) || presence.Equals (_offline)
				|| presence.Equals (_away) || presence.Equals (_dnd)
				|| presence.Equals (_na) || presence.Equals (_occupied)
				|| presence.Equals (_freeforchat) || presence.Equals (_invisible);
		}
		
		public static bool IsValidAimPresence (ushort presence)
		{
			return ushort.Equals (presence, (ushort)ICQStatus.Away)
				|| ushort.Equals (presence, (ushort)ICQStatus.DoNotDisturb)
				|| ushort.Equals (presence, (ushort)ICQStatus.FreeForChat)
				|| ushort.Equals (presence, (ushort)ICQStatus.Invisible)
				|| ushort.Equals (presence, (ushort)ICQStatus.NotAvailable)
				|| ushort.Equals (presence, (ushort)ICQStatus.Occupied)
				|| ushort.Equals (presence, (ushort)ICQStatus.Online);
		}
		
		public static IPresence ParseAimPresence (ushort presence)
		{
			if (ushort.Equals (presence, (ushort)ICQStatus.Online)) {
				return Online;
			} else if (ushort.Equals (presence, (ushort)ICQStatus.Away)) {
				return Away;
			} else if (ushort.Equals (presence, (ushort)ICQStatus.DoNotDisturb)) {
				return Dnd;
			} else if (ushort.Equals (presence, (ushort)ICQStatus.NotAvailable)) {
				return Na;
			} else if (ushort.Equals (presence, (ushort)ICQStatus.Occupied)) {
				return Occupied;
			} else if (ushort.Equals (presence, (ushort)ICQStatus.FreeForChat)) {
				return FreeForChat;
			} else if (ushort.Equals (presence, (ushort)ICQStatus.Invisible)) {
				return Invisible;
			}
			
			return UnknownPresence.Instance;
		}
		
		public static string GetIconString (IPresence presence)
		{
			//TODO: fix the icon names a bit
			if (presence.Equals (AimPresence.Online))
				return "galaxium-status-online";
			else if (presence.Equals (AimPresence.Away))
				return "galaxium-status-away";
			else if (presence.Equals (AimPresence.Dnd))
				return "galaxium-status-brb";
			else if (presence.Equals (AimPresence.Na))
				return "galaxium-status-busy";
			else if (presence.Equals (AimPresence.Occupied))
				return "galaxium-status-busy";
			else if (presence.Equals (AimPresence.FreeForChat))
				return "galaxium-status-online";
			else if (presence.Equals (AimPresence.Invisible))
				return "galaxium-status-invisible";
			else
				return "galaxium-status-offline";
		}
		
		public static ushort GetAimPresenceCode (IPresence presence)
		{
			if (presence.Equals (AimPresence.Online))
				return (ushort)ICQStatus.Online;
			else if (presence.Equals (AimPresence.Away))
				return (ushort)ICQStatus.Away;
			else if (presence.Equals (AimPresence.Dnd))
				return (ushort)ICQStatus.DoNotDisturb;
			else if (presence.Equals (AimPresence.Na))
				return (ushort)ICQStatus.NotAvailable;
			else if (presence.Equals (AimPresence.Occupied))
				return (ushort)ICQStatus.Occupied;
			else if (presence.Equals (AimPresence.FreeForChat))
				return (ushort)ICQStatus.FreeForChat;
			else if (presence.Equals (AimPresence.Invisible))
				return (ushort)ICQStatus.Invisible;
			else
				return (ushort)0;
		}
	}
	
	internal sealed class OnlinePresence : AbstractPresence
	{
		public OnlinePresence ()
		{
			base._basePresence = BasePresence.Online; 
		}
		
		public override string Icon
		{
			get { return "galaxium-tray-online"; }
		}
		
		public override string State
		{
			get { return "Online"; }
		}
	}
	
	internal sealed class OfflinePresence : AbstractPresence
	{
		public OfflinePresence ()
		{
			_basePresence = BasePresence.Offline; 
		}
		
		public override string Icon
		{
			get { return "galaxium-tray-offline"; }
		}
		
		public override string State
		{
			get { return "Offline"; }
		}
	}
	
	internal sealed class DndPresence : AbstractPresence
	{
		public DndPresence ()
		{
			_basePresence = BasePresence.Away; 
		}
		
		public override string Icon
		{
			get { return "galaxium-tray-busy"; }
		}
		
		public override string State
		{
			get { return "Do Not Disturb"; }
		}
	}
	
	internal sealed class NaPresence : AbstractPresence
	{
		public NaPresence ()
		{
			_basePresence = BasePresence.Away; 
		}
		
		public override string Icon
		{
			get { return "galaxium-tray-brb"; }
		}
		
		public override string State
		{
			get { return "Not Available"; }
		}
	}
	
	internal sealed class OccupiedPresence : AbstractPresence
	{
		public OccupiedPresence ()
		{
			_basePresence = BasePresence.Away; 
		}
		
		public override string Icon
		{
			get { return "galaxium-tray-busy"; }
		}
		
		public override string State
		{
			get { return "Occupied"; }
		}
	}
	
	internal sealed class AwayPresence : AbstractPresence
	{
		public AwayPresence ()
		{
			_basePresence = BasePresence.Away; 
		}
		
		public override string Icon
		{
			get { return "galaxium-tray-away"; }
		}
		
		public override string State
		{
			get { return "Away"; }
		}
	}
	
	internal sealed class FreeForChatPresence : AbstractPresence
	{
		public FreeForChatPresence ()
		{
			_basePresence = BasePresence.Online; 
		}
		
		public override string Icon
		{
			get { return "galaxium-tray-online"; }
		}
		
		public override string State
		{
			get { return "Free For Chat"; }
		}
	}
	
	internal sealed class InvisiblePresence : AbstractPresence
	{
		public InvisiblePresence ()
		{
			_basePresence = BasePresence.Invisible; 
		}
		
		public override string Icon
		{
			get { return "galaxium-tray-invisible"; }
		}
		
		public override string State
		{
			get { return "Invisible"; }
		}
	}
}